import React from 'react'
import style from './style'
import cx from 'classnames'
import rule, { msg } from './rule'
import util from '../../util'
import rules from '../../libs/rule'
import SelectList from '../selectList'
import SelectItem from './SelectItem'
import ReactCSSTransitionGroup from 'react/lib/ReactCSSTransitionGroup';
import {FieldContainer, FieldBox} from '../form'

import Check from './Check';

export default
class MulSelect  extends React.Component {

	static defaultProps = {
		raised: true,
    value: [],
    excludeList: [],
		onChange: () => {},
		onFocus: () => {},
		onBlur: () => {}
	}
  constructor(props) {
    super(props)
    this.state = {
      error: false,
      active: false,
      canDel: false,
      curValue: '',
    }

    this.rule = rules[props.name] || {}

    const regex = props.regex? new RegExp(props.regex): this.rule.regex
    if (regex) {
      this.regex = regex
    }
  }
  componentDidMount() {
    if ((this.props.value && this.props.value.length) || this.props.defaultValue) {
      this.setState({
        filled: true
      })
      if (this.props.autoFocus) {
        setTimeout(() => {
          this.setState({
            active: true
          })
          this.refs.input.focus()
        }, 150)
      }
    }
  }
  componentDidUpdate() {
    const { state, props } = this;
    const inputNode = this.refs.searchInput;
    const mirrorNode = this.refs.selectMirror;
    if (inputNode.value) {
      inputNode.style.width = '';
      inputNode.style.width = `${mirrorNode.clientWidth}px`;
    } else {
      inputNode.style.width = '';
    }
  }

	focus() {
		this.refs.input.focus()
	}
  
  handleFocus(e) {
    this.setState({
      active: true
    })
    this.props.onFocus(e)
  }
	handleBlur() {
    this.setState({
      active: false,
      curValue: '',
    })  
	}
  handleKeyDown(e) {
    const { which } = e
    if(!this.state.curValue && which === 8) {
      let {value = []} = this.props;
      for(let length = value.length,i = length -1; i >= 0; i--) {
        value.splice(i,1);
        break;
      }
      this.props.onSelect && this.props.onSelect(value);
    }
    
  }
	value() {
		return this.refs.searchInput.value
	}
	error(msg) {
		this.setState({
			error: true,
			msg
		})
	}
	reset() {
		this.refs.input.blur()
		this.setState({
			filled: false,
			error: false,
      active: false,
		})
	}
  handleChange(e) {
    const { value='' } = e.target;
    if(this.props.tree) return;
    this.props.fetch(value);
    this.setState({
      curValue: value,
    });
  }
  handleSelect(i) {
    const data = this.refs.selectList.props.data;
    if(i >= data.length) return;
    const selected = data[i];
    this.props.fetch('');
    this.setState({
      curValue: ''
    })
    this.props.onSelect && this.props.onSelect([...(this.props.value||[]), selected]);
  }
  handleDel(i) {
    const {value} = this.props;
    value.splice(i, 1);
    this.props.onSelect && this.props.onSelect(value);
  }
  // filter exclude list
  filter(source, exclude) {
    if(this.props.filter) return this.props.filter(source, exclude);
    let arr
    if (Array.isArray(source)) {
      arr = source
    } else if (typeof source === 'object') {
      arr = source[this.state.curValue] || []
    }
    return arr.filter(item => exclude.every(v => v.userId != item.userId))
  }
  showInput() {
    if(this.props.disabled) return;
    const {
      searchInput
    } = this.refs;
    this.setState({
      active: true,
    });
    searchInput.focus();
  }
  handleClick(e, item) {
    e.preventDefault()
  }
  ulClick = (e) => {
  }
  handleMulClick = (e, item) => {
    const flag = e;
    const {
      value,
      root
    } = this.props;
    if(flag){
      const cleanList = [];
      const cleanFn = (team) => {
        const cleanItem = value.find(v => v.teamId === team.teamId);
        if(cleanItem)
          cleanList.push(cleanItem);
        if(team.teams)
          team.teams.map(v => cleanFn(v))
      } 
      cleanFn(item);
      this.props.onClick([...value.filter(v => !~cleanList.findIndex(f => v.teamId === f.teamId)), item]);
    }else{
      this.props.onClick(value.filter(v => v.teamId !== item.teamId))
    }
  }
  getTree = () => {
    const {value}  = this.props;
    const render = (team, flag) => team.teams? (
      <ul className={style['tree-ul']} onClick={this.ulClick}>
        {
          team.teams.map((item, i) => {
            let isCheck = flag;
            if(!flag)
              isCheck = !!~value.findIndex(v => v.teamId === item.teamId );
            return (
              <li key={i} onMouseDown={e => this.handleClick(e, item)}>
                <Check checked={isCheck} disabled={flag} onChange={e => this.handleMulClick(e, item)} 
                  label={item.teamName}
                />
                { render(item, isCheck) }
              </li> 
            )
          })
        }
     </ul>
    ): null
    const {
      active,
    } = this.state;
    return !active ? null : (
      <div className={style['tree-area']}>
        {render(this.props.root)}
      </div>
    );
  }
  onKeyPress = (e) => {
    if(e.charCode === 13){
      this.props.onEnter && this.props.onEnter();
    }
    return false;
  }
	render() {
    const {
      curValue,
      active
    } = this.state;
		const { value = [], initValue = [], excludeList = [],onChange,
      options, ...others } = this.props;
    const { item,tree,selectItemStyle,lineStyle,tip, disabled, required,placeholder, multi,type='text', width,attr, name, regex, className, label, error, bubbleList } = this.props
		const selectProps = item ? {item} : {};
    return (
			<FieldBox
          label={label}
          name={name}
          required={required}
          tip={tip}
        >
          <FieldContainer
            hasBox={true}
            active={this.state.active}
            error={this.state.error}
            disabled={disabled}
            msg={this.state.msg}
            className={className}
            bubbleList={bubbleList}
            width={width}
            lineStyle
          >
            <div onClick={::this.showInput} data-role="input"
              className={cx({
                [style.root]: true,
                [className]: !!className,
                [style.filled]: initValue.length || value.length || this.state.filled,
              })}
            >
              <ReactCSSTransitionGroup 
                transitionName={{
                  enter: style['select-li-enter'],
                  enterActive: style['select-li-enter-active'],
                  leave: style['select-li-leave'],
                  leaveActive: style['select-li-leave-active'],
                }} 
                component={'ul'} 
                transitionEnterTimeout={300} 
                transitionLeaveTimeout={300}
                className={style['select-value-area']}
              >
                {
                  initValue.map((item, i) => {
                    if(!item) return;
                    const attrs = this.props.getItemAttrs ? this.props.getItemAttrs(item) : {}
                    return <SelectItem key={i} item={item} {...attrs} notDel/>
                  })
                }
                {
                  value.map((item, i) => {
                    const attrs = this.props.getItemAttrs ? this.props.getItemAttrs(item) : {}
                    return <SelectItem className={selectItemStyle} noImg={tree || this.props.noImg} key={i} item={item} {...attrs} notDel={!!disabled} index={i} onDel={::this.handleDel}/>
                  })
                }
                <li style={{display: disabled ? 'none' : 'inline-block'}}>
                  <div className={style['select-search']}>
                    <input
                      ref={'searchInput'}
                      className={style['select-input']}
                      onFocus={::this.handleFocus}
                      onBlur={::this.handleBlur}
                      onKeyDown={::this.handleKeyDown}
                      onChange={::this.handleChange}
                      value={curValue}
                      onKeyPress={this.onKeyPress}
                    />
                    <span ref={'selectMirror'}>{curValue}</span>
                    
                  </div>
                </li>
              </ReactCSSTransitionGroup>
              {initValue.length || value.length || curValue.length ? 
                null
                : <span className={style.placeholder}>{placeholder}</span>
              }
      				<span className={style.msg}>{this.state.msg}</span>
              {
                tree ? this.getTree() :
                <SelectList
                  ref={'selectList'}
                  handleSelect={::this.handleSelect}
                  data={this.filter(options, [...initValue, ...value, ...excludeList])}
                  show={active}
                  query={curValue}
                  className={style.list}
                  {...selectProps}
                />
              }
      			
            </div>
			  </FieldContainer>
      </FieldBox>
		)
	}
}
